from datetime import datetime

from django.contrib.auth.hashers import make_password, check_password
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView

from utils.JwtTools import JwtTool
from utils.RedisTools import RedisTool
from utils.Smstools import SmsTool
from .models import User,Addr
import re
# Create your views here.

import random,string
from captcha.image import ImageCaptcha
from django.http import HttpResponse
import redis
# 生成图形验证码
class ImgCode(APIView):
    def get(self,request,uuid):
        # 1.生成4位验证码
        code=''.join(random.sample(string.ascii_letters+string.digits,4))
        print(code)
        # 2.生成图形验证码
        cap=ImageCaptcha() #定义对象
        img_code=cap.generate(code) #生成图形验证码的图片
        # 3.保存验证码
        r=redis.Redis(host='localhost',port=6379,db=0)
        r.set(str(uuid),code,ex=120)
        r.close()
        # 4.返回图形验证码，使用HttpResponce返回，需要加上数据类型content_type
        return HttpResponse(img_code,content_type='image/png')

# 校验验证码
class CheckImgCode(APIView):

    def post(self,request):
        # 提取POST参数中的uuid和验证码
        uuid = request.data.get('imageCodeID')
        img_code = request.data.get('imageCode')
        # 2.读取reids数据库中的验证码
        r=redis.Redis(host='localhost',port=6379,db=0)
        r_code=r.get(uuid).decode()
        if not r_code: #读取不到
            return Response({'code':204,'msg':'验证码过期'})
        print(img_code)
        print(r_code)
        # redis数据库存的是二进制
        if img_code.lower()==r_code.lower():
            return Response({'code':200,'msg':'OK'})
        else:
            return Response({'code': 404, 'msg': '验证码错误'})
# 注册
class Register(APIView):
    def post(self,request):
        # 获取前端提交的数据
        code=request.data.get('code')
        pwd=request.data.get('password')
        mobile=request.data.get('mobile')
        print(pwd,mobile,code)
        # 2.判断信息是否齐全
        if not all([code,pwd,mobile]):
            return Response({'code':204,'msg':'注册信息不完整'})
        if RedisTool().rds.get('sms_'+mobile).decode()!=code:
            return Response({'code': 400, 'msg': '验证码已过期'})
        # 判断手机号是否存在
        if not re.findall(r'^1[3-9]\d{9}$', mobile):
            return Response({'code': 404, 'msg': '手机号不存在'})
        # 判断手机号是否注册
        if User.objects.filter(mobile=mobile):
            return Response({'code': 400, 'msg': '手机号已注册'})
        # 4.往数据库中保存数据
        password=make_password(pwd)
        username='用户'+mobile[-4:]
        User.objects.create(username=username,password=password,mobile=mobile)
        return Response({'code':200,'msg':'注册成功'})

class SmsCode(APIView):
    def get(self,request,mobile):
        # 校验参数
        rule=r'^1[3-9]\d{9}$'
        if not re.findall(rule,mobile):
            return Response({
                'code':400,
                'msg':'手机号格式不正确'
            })
        # 随机生成6位验证码
        code=random.randint(100000,999999)
        # 存入 redis数据库
        r=RedisTool().rds
        r.set(f'sms_{mobile}',code,ex=5*60)
        r.close()
        res=SmsTool().send_code(mobile,code)
        if not res:
            return Response({'code':400,"msg":'验证码发送失败'})
        return Response({'code':200,"msg":'验证码发送成功'})




class Login(APIView):
    def post(self,request):
        # 1.获取 手机号 密码
        mobile=request.data.get('mobile')
        pwd=request.data.get('password')
        # 2.获取数据库中的数据，判断用户名是否存在
        try:
            from django.db.models import Q
            user=User.objects.get(Q(username=mobile)|Q(mobile=mobile))
            user.last_login=datetime.now()
            user.save()
        except Exception as e:
            print(e)
            return Response({'code':204,'msg':'用户名不存在'})
        # 判断密码是否正确
        if not check_password(pwd,user.password):
            return Response({'code':204,'msg':'用户名或密码错误'})
        print(user)
        token=JwtTool().create_jwt(user)
        return Response({
            'code':200,
            'token':token,
            'msg':f'欢迎用户{user.username}登录',
        })
from .serializers import AddrSer


class UserCenter(APIView):
    def get(self,request):
        # 1.判断用户是否登录
        try:
            user_info = request.user_info
            user = User.objects.get(id=user_info.get("id"))
        except Exception as e:
            print(e)
            return Response({'msg': '用户不存在或未登录', 'code': 204})
        # 2.返回前端需要的数据
        addr_list=[]
        #查询用户的地址信息
        addrs_data=user.addr_set.all()
        #使用序列化器序列化
        # ser=AddrSer(addrs_data,many=True)
        # 手动序列化
        for i in addrs_data:
            addr_list.append({
                'id':i.id,
                'receiver':i.receiver,
                'receive_mobile':i.receive_mobile,
                'receive_addr':i.receive_addr,
                'is_default':i.is_default
            })
        return Response({
            'code':200,
            'msg':'获取用户信息成功',
            'userInfo':{
            'username':user.username,
            'phone':user.mobile,
            'addrs':addr_list
            }
        })
    def put(self,request):
        # 1.判断用户是否登录
        try:
            user_info = request.user_info
            user = User.objects.get(id=user_info.get("id"))
        except Exception as e:
            print(e)
            return Response({'msg': '用户不存在或未登录', 'code': 204})
        # 2.获取前端提交的数据
        phone=request.data.get('phone')
        addes_list=request.data.get('addrs')
        # 3.修改用户手机号
        if not re.findall(r'^1[3-9]\d{9}$',phone):
            return Response({'msg': '手机号不正确', 'code': 204})
        user.mobile=phone
        user.save()
        # 4.修改地址 循环一个一个去修改
        for i in addes_list:
            Addr.objects.filter(id=i.get('id')).update(
                receiver=i.get('receiver'),
                receive_mobile=i.get('receive_mobile'),
                receive_addr=i.get('receive_addr'),
                is_default=i.get('is_default'),
            )
        return Response({'msg': '修改成功', 'code': 200})
class AddrInfo(APIView):
    def post(self,request):
        # 1.判断用户是否登录
        try:
            user_info = request.user_info
            user = User.objects.get(id=user_info.get("id"))
        except Exception as e:
            print(e)
            return Response({'msg': '用户不存在或未登录', 'code': 204})
        # 2.获取前端传的数据
        receiver=request.data.get('receiver')
        receive_mobile=request.data.get('receive_mobile')
        receive_addr=request.data.get('receive_addr')
        is_default=request.data.get('is_default')
        # 3.判断数据是否齐全，手机号是否符合要求
        if not all([receiver,receive_mobile,receive_addr]):
            return Response({'code':204,'msg':'信息不齐全'})
        if not re.findall(r'^1[3-9]\d{9}$',receive_mobile):
            return Response({'code':204,'msg':'手机号不正确'})
        # 4.默认收货地址处理：只能有一个
        if is_default:
            #查看用户是否有默认地址
            default_addr=Addr.objects.filter(user=user,is_default=True)
            default_addr.update(is_default=False)
        # 5.添加新地址
        new_addr=Addr.objects.create(
            receiver=receiver,
            receive_mobile = receive_mobile,
            receive_addr = receive_addr,
            is_default =is_default,
            user=user
        )
        ser=AddrSer(new_addr)
        return Response({'code':200,'msg':'添加地址信息成功','addr':ser.data})
    def delete(self,request):
        # 1.判断用户是否登录
        try:
            user_info = request.user_info
            user = User.objects.get(id=user_info.get("id"))
        except Exception as e:
            print(e)
            return Response({'msg': '用户不存在或未登录', 'code': 204})
        # 2.获取要删除的数据 地址id
        addr_id=request.data.get('addr_id')
        # 3.删除地址
        Addr.objects.filter(id=addr_id).delete()
        return Response({'msg': '删除成功', 'code': 200})
    def get(self,request):
        # 1.判断用户是否登录
        try:
            user_info = request.user_info
            user = User.objects.get(id=user_info.get("id"))
        except Exception as e:
            print(e)
            return Response({'msg': '用户不存在或未登录', 'code': 204})
        # 2.获取用户地址信息
        addrs_data=user.addr_set.all()
        ser=AddrSer(addrs_data,many=True)
        return Response({'msg': 'OK!', 'code': 200,'addrList':ser.data})

class Update(APIView):
    def put(self,request):
        # 1.判断用户是否登录
        try:
            user_info = request.user_info
            user = User.objects.get(id=user_info.get("id"))
        except Exception as e:
            print(e)
            return Response({'msg': '用户不存在或未登录', 'code': 204})
        # 2.获取前端传的数据
        originPw=request.data.get('originPw')
        newPw=request.data.get('newPw')
        confirmNewPw=request.data.get('confirmNewPw')
        # 3.判断原始密码是否正确
        if not user.check_password(originPw):
            return Response({'msg': '密码错误', 'code': 204})
        # 4.判断 原密码 和 新密码 是否一样
        if originPw==newPw:
            return Response({'msg': '密码没有修改', 'code': 204})
        # 5.判断两次新密码是否一致
        if newPw!=confirmNewPw:
            return Response({'msg': '两次密码不一致', 'code': 204})
        # 6.保存新密码
        user.set_password(newPw)
        user.save()
        return Response({'msg': '修改密码成功', 'code': 200})







